#define MAINWINDOW_CPP
#include "dcmtk/config/osconfig.h"
#include "dcmtk/dcmpstat/dviface.h"
#include "mainwindow.h"
#include "../share/configfiles.h"
#include "../share/global.h"
#include "../share/studyrecord.h"
#include "ui_mainwindow.h"
#include "timelabel.h"
#include "freespacelabel.h"
#include "../DicomService/storescpthread.h"
#include "../Worklist/studyregisterwidget.h"
#include "studyexplorerwidget.h"
#include "archivewidget.h"
#include "systemsettingswidget.h"
#include "exitwidget.h"
#include "../StructuredReport/reporteditwidget.h"
#include "../ImageView/imageviewwidget.h"
#include "../ImageView/thumbnailbarwidget.h"
#include "studydbmanager.h"
#include "logdbmanager.h"
#include "logindialog.h"
#include "setlicencedialog.h"

#include <QCloseEvent>
#include <QSplashScreen>
#include <QVBoxLayout>
#include <QMessageBox>
#include <QSqlError>
#include <QSqlQuery>
#include <QTimer>
#include <QSettings>

MainWindow::MainWindow(QWidget *parent) :
    prevTab(0),
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    init();
}

MainWindow::MainWindow(const User &u, const Group &g, QWidget *parent) :
    currentUser(u),
    currentGroup(g),
    prevTab(0),
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    init();
}

MainWindow::~MainWindow()
{
    storeScp->terminate();
    delete ui;
}

void MainWindow::init()
{
    mainWindow = this;

    QSplashScreen splash(QPixmap(":/images/splash.jpg"));
    splash.show();

    splash.showMessage(tr("Creating modules..."), Qt::AlignCenter, Qt::green);
    createComponents();
    setupComponents();
    createConnections();

    storeScp->start();
    settingsTab->resetScps();
    QTimer::singleShot(5000, this, SLOT(verifyLicence()));
}

void MainWindow::createComponents()
{
    settingsTab = new SystemSettingsWidget;
    studyExplorerTab = new StudyExplorerWidget;
    imageViewTab = new ImageViewWidget;
    reportEditTab = new ReportEditWidget(this);
    reportEditTab->hide();
    reportProxyWidget = new QWidget;
    archiveTab = new ArchiveWidget;
    exitTab = new ExitWidget;
    registerTab = new StudyRegisterWidget;
    fspaceLabel = new FreeSpaceLabel;
    storeScp = new StoreScpThread(this);
}

void MainWindow::setupComponents()
{
    ui->tabWidget->addTab(registerTab, tr("Patient Register"));
    ui->tabWidget->addTab(studyExplorerTab, tr("Explore Study"));
    ui->tabWidget->addTab(imageViewTab, tr("Image View"));
    ui->tabWidget->addTab(reportProxyWidget, tr("Report Edit"));
    ui->tabWidget->addTab(archiveTab, tr("Archive Utilities"));
    ui->tabWidget->addTab(settingsTab, tr("System Settings"));
    ui->tabWidget->addTab(exitTab, tr("Exit"));
    ui->tabWidget->setCurrentWidget(studyExplorerTab);
    prevTab = studyExplorerTab;

    thumbnailBarList << imageViewTab->getThumbnailBar() <<
                        reportEditTab->getThumbnailBar();

    statusBar()->addPermanentWidget(fspaceLabel);
    statusBar()->addPermanentWidget(new QLabel(tr("User: %1 ").arg(currentUser.name)));
    statusBar()->addPermanentWidget(new QLabel(tr("Group: %1 ").arg(currentGroup.name)));
    statusBar()->addPermanentWidget(new TimeLabel);
}

void MainWindow::createConnections()
{
    connect(this, SIGNAL(statusBarMsg(QString)), ui->statusBar, SLOT(showMessage(QString)));
    connect(ui->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(onCurrentTabChanged()));
    connect(storeScp, SIGNAL(imageReceived(QString)), studyExplorerTab, SIGNAL(refreshStudyTable()));
    connect(storeScp, SIGNAL(imageReceived(QString)), this, SIGNAL(statusBarMsg(QString)));

    connect(settingsTab, SIGNAL(printScpUpdated(QList<DicomScp*>)),
            imageViewTab, SLOT(onPrintScpUpdated(QList<DicomScp*>)));
    connect(settingsTab, SIGNAL(dbLocationChanged()),
            fspaceLabel, SLOT(detectFreeSpace()));
    connect(settingsTab, SIGNAL(qrScpUpdated(QList<DicomScp*>)),
            studyExplorerTab, SLOT(onQrScpUpdated(QList<DicomScp*>)));

    connect(studyExplorerTab, SIGNAL(viewImages(QStringList)),
            this, SLOT(onViewImages(QStringList)));
    connect(studyExplorerTab, SIGNAL(createReport(QString)),
            this, SLOT(onCreateReport(QString)));
    connect(studyExplorerTab, SIGNAL(viewReports(QStringList)),
            this, SLOT(onviewReports(QStringList)));

    connect(reportEditTab, SIGNAL(removeImage(QString)), this, SLOT(onRemoveImage(QString)));
    connect(imageViewTab, SIGNAL(removeImage(QString)), this, SLOT(onRemoveImage(QString)));
    connect(archiveTab, SIGNAL(importFinished()), studyExplorerTab, SIGNAL(refreshStudyTable()));
}

void MainWindow::onRemoveImage(const QString &imageUid)
{
    if (StudyDbManager::removeImageFromDb(imageUid)) {
        foreach (ThumbnailBarWidget *t, thumbnailBarList) {
            t->removeImageFromBar(imageUid);
        }
    }
}

void MainWindow::onViewImages(const QStringList &imageFiles)
{
    //imageViewTab->setImageFiles(imageFiles);
    imageViewTab->setObserveMode(true);
    ui->tabWidget->setCurrentWidget(imageViewTab);
}

void MainWindow::onCreateReport(const QString &studyUid)
{
    reportEditTab->createReport(studyUid);
    reportEditTab->show();
}

void MainWindow::onviewReports(const QStringList &reportFiles)
{
    reportEditTab->openReports(reportFiles);
    reportEditTab->show();
}

void MainWindow::onCurrentTabChanged()
{
    QWidget *widget = ui->tabWidget->currentWidget();

    if (widget == imageViewTab) {
        imageViewTab->setObserveMode(true);
        if (prevTab == studyExplorerTab) {
            imageViewTab->setImageFiles(studyExplorerTab->getAllImageFiles());
        }
        prevTab = widget;
    } else if (widget == reportProxyWidget) {
        if (reportEditTab->isHidden()) {
            bool noStudy = true;
            if (prevTab == imageViewTab) {
                StudyRecord study;
                if (imageViewTab->getCurrentStudy(study)) {
                    if (!reportEditTab->setActiveReport(study.studyUid))
                        studyExplorerTab->openOrCreateReport(study.studyUid);
                    reportEditTab->show();
                    noStudy = false;
                }
            } else if (prevTab == studyExplorerTab) {
                if (studyExplorerTab->openOrCreateReportOfCurrentStudy())
                    noStudy = false;
            }

            ui->tabWidget->setCurrentWidget(prevTab);
            if (noStudy) {
                if (QMessageBox::question (this, tr("Edit Report"),
                                          tr("A study should be selected first, select one now?"),
                                          QMessageBox::Yes|QMessageBox::No) == QMessageBox::Yes) {
                    //prevTab = widget;
                    ui->tabWidget->setCurrentWidget(studyExplorerTab);
                }
            }
        } else {
            ui->tabWidget->setCurrentWidget(prevTab);
        }
    } else if (widget == settingsTab) {
        settingsTab->initIdStarts();
        prevTab = widget;
    } else {
        prevTab = widget;
    }
}

const InstitutionInfo& MainWindow::getInstInfo() const
{
    return settingsTab->getInstInfo();
}

const ManufactureInfo& MainWindow::getManuInfo() const
{
    return settingsTab->getManuInfo();
}

const StationInfo& MainWindow::getStationInfo() const
{
    return settingsTab->getStationInfo();
}

const DatabaseConfig& MainWindow::getDbConfig() const
{
    return settingsTab->getDbConfig();
}

const CustomizedId& MainWindow::getPatientIdFormat() const
{
    return settingsTab->getPatientIdFormat();
}

const CustomizedId& MainWindow::getAccNumFormat() const
{
    return settingsTab->getAccNumFormat();
}

bool MainWindow::savelyClose() const
{
    return reportEditTab->close();
}

bool MainWindow::lockStation() const
{
    return LoginDialog::userLogin();
}

void MainWindow::closeEvent(QCloseEvent *e)
{
    if (ui->tabWidget->currentWidget()!=exitTab) {
        ui->tabWidget->setCurrentWidget(exitTab);
        e->ignore();
    } else if (!savelyClose()){
        e->ignore();
    }
}

void MainWindow::verifyLicence()
{
    QSettings s;
    qint64 last = s.value(LAST_VERIFIED, 0).toLongLong();
    qint64 now = QDateTime::currentMSecsSinceEpoch();
    if (last >= now) {
        QMessageBox::critical(this, tr("System Error"),
                              tr("System time error, reset expire date."));
        setDaysCount(MY_BIRTH.daysTo(QDate(2000,1,1)));
    } else {
        s.setValue(LAST_VERIFIED, now);
    }

    if (!SetLicenceDialog::verifyExpireDate()) {
        QMessageBox::warning(this, tr("Licence Expired"),
                             tr("Licence expired, about to exit."));
        ui->tabWidget->setCurrentWidget(exitTab);
        close();
    }

    QTimer::singleShot(1800000, this, SLOT(verifyLicence()));
}
